import { app, shell, BrowserWindow, ipcMain, globalShortcut } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'

let mainWindow: BrowserWindow | null = null
const detachedWindows: Map<number, BrowserWindow> = new Map()
const detachedNoteData: Map<number, DetachedNote> = new Map()

interface DetachedNote {
  id: number
  title: string
  content: string
  createdAt: Date
  updatedAt: Date
}

interface SerializableNote {
  id: number
  title: string
  content: string
  createdAt: string
  updatedAt: string
}

function createWindow(): void {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1400,
    height: 900,
    minWidth: 1000,
    minHeight: 700,
    show: false,
    autoHideMenuBar: true,
    maximizable: true,
    resizable: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  mainWindow.on('ready-to-show', () => {
    if (mainWindow) {
      mainWindow.show()
      // 窗口显示后立即最大化
      mainWindow.maximize()
    }
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

// 创建脱出窗口
function createDetachedWindow(note: DetachedNote): void {
  console.log('开始创建脱出窗口，note:', note.title)

  const detachedWindow = new BrowserWindow({
    width: 800,
    height: 600,
    minWidth: 600,
    minHeight: 400,
    show: false,
    autoHideMenuBar: true,
    maximizable: true,
    resizable: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  console.log('脱出窗口已创建，ID:', note.id)

  // 存储窗口引用和note数据
  detachedWindows.set(note.id, detachedWindow)
  detachedNoteData.set(note.id, note)

  detachedWindow.on('ready-to-show', () => {
    console.log('脱出窗口准备显示')
    detachedWindow.show()
  })

  detachedWindow.on('closed', () => {
    console.log('脱出窗口已关闭，ID:', note.id)

    // 在窗口关闭时，将note数据发送回主窗口
    if (mainWindow && !mainWindow.isDestroyed()) {
      const noteData = detachedNoteData.get(note.id)
      if (noteData) {
        console.log('发送note回到主窗口:', noteData.title)
        mainWindow.webContents.send('note-returned', {
          id: noteData.id,
          title: noteData.title,
          content: noteData.content,
          createdAt: noteData.createdAt.toISOString(),
          updatedAt: noteData.updatedAt.toISOString()
        })
      }
    }

    detachedWindows.delete(note.id)
    detachedNoteData.delete(note.id)
  })

  detachedWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // 加载相同的页面
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    console.log('加载开发环境URL')
    detachedWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    console.log('加载生产环境HTML文件')
    detachedWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

// 切换窗口置顶状态
function toggleAlwaysOnTop(): void {
  if (mainWindow) {
    const isAlwaysOnTop = mainWindow.isAlwaysOnTop()
    mainWindow.setAlwaysOnTop(!isAlwaysOnTop)

    // 通知渲染进程状态变化
    mainWindow.webContents.send('always-on-top-changed', !isAlwaysOnTop)

    console.log(`窗口置顶状态: ${!isAlwaysOnTop ? '已开启' : '已关闭'}`)
  }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // 注册全局快捷键 Ctrl+Shift+T 切换置顶
  globalShortcut.register('CommandOrControl+Shift+T', () => {
    toggleAlwaysOnTop()
  })

  // IPC handlers
  ipcMain.on('ping', () => console.log('pong'))

  // 处理来自渲染进程的置顶切换请求
  ipcMain.handle('toggle-always-on-top', () => {
    toggleAlwaysOnTop()
    return mainWindow?.isAlwaysOnTop() || false
  })

  // 获取当前置顶状态
  ipcMain.handle('get-always-on-top', () => {
    return mainWindow?.isAlwaysOnTop() || false
  })

  // 处理创建脱出窗口请求
  ipcMain.handle('create-detached-window', (_, serializableNote: SerializableNote) => {
    console.log('收到创建脱出窗口请求:', serializableNote.title)
    try {
      // 将序列化的note转换为包含Date对象的note
      const note: DetachedNote = {
        id: serializableNote.id,
        title: serializableNote.title,
        content: serializableNote.content,
        createdAt: new Date(serializableNote.createdAt),
        updatedAt: new Date(serializableNote.updatedAt)
      }

      createDetachedWindow(note)
      console.log('脱出窗口创建成功')
      return { success: true }
    } catch (error) {
      console.error('创建脱出窗口失败:', error)
      return { success: false, error: error instanceof Error ? error.message : String(error) }
    }
  })

  // 获取脱出note数据（用于新窗口初始化）
  ipcMain.handle('get-detached-note', (event) => {
    const window = BrowserWindow.fromWebContents(event.sender)
    if (!window) return null

    // 查找是否是脱出窗口
    for (const [noteId, detachedWindow] of detachedWindows) {
      if (detachedWindow === window) {
        return detachedNoteData.get(noteId) || null
      }
    }
    return null
  })

  // 更新脱出窗口中的note数据
  ipcMain.handle('update-detached-note', (event, serializableNote: SerializableNote) => {
    const window = BrowserWindow.fromWebContents(event.sender)
    if (!window) return { success: false, error: '窗口未找到' }

    // 查找是否是脱出窗口
    for (const [noteId, detachedWindow] of detachedWindows) {
      if (detachedWindow === window && noteId === serializableNote.id) {
        // 更新存储的note数据
        const updatedNote: DetachedNote = {
          id: serializableNote.id,
          title: serializableNote.title,
          content: serializableNote.content,
          createdAt: new Date(serializableNote.createdAt),
          updatedAt: new Date(serializableNote.updatedAt)
        }
        detachedNoteData.set(noteId, updatedNote)
        console.log('脱出窗口note数据已更新:', updatedNote.title)
        return { success: true }
      }
    }
    return { success: false, error: '未找到对应的脱出窗口' }
  })

  // 切换脱出窗口置顶状态
  ipcMain.handle('toggle-detached-window-always-on-top', (event) => {
    const window = BrowserWindow.fromWebContents(event.sender)
    if (!window) return { success: false, error: '窗口未找到' }

    // 检查是否是脱出窗口
    for (const [, detachedWindow] of detachedWindows) {
      if (detachedWindow === window) {
        const isAlwaysOnTop = window.isAlwaysOnTop()
        window.setAlwaysOnTop(!isAlwaysOnTop)

        // 通知渲染进程状态变化
        window.webContents.send('detached-window-always-on-top-changed', !isAlwaysOnTop)

        console.log(`脱出窗口置顶状态: ${!isAlwaysOnTop ? '已开启' : '已关闭'}`)
        return { success: true, isAlwaysOnTop: !isAlwaysOnTop }
      }
    }
    return { success: false, error: '未找到对应的脱出窗口' }
  })

  // 获取脱出窗口置顶状态
  ipcMain.handle('get-detached-window-always-on-top', (event) => {
    const window = BrowserWindow.fromWebContents(event.sender)
    if (!window) return { success: false, error: '窗口未找到' }

    // 检查是否是脱出窗口
    for (const [, detachedWindow] of detachedWindows) {
      if (detachedWindow === window) {
        return { success: true, isAlwaysOnTop: window.isAlwaysOnTop() }
      }
    }
    return { success: false, error: '未找到对应的脱出窗口' }
  })

  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  // 清理全局快捷键
  globalShortcut.unregisterAll()

  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// 当应用即将退出时清理快捷键
app.on('will-quit', () => {
  globalShortcut.unregisterAll()
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
